﻿using ScFramework.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[DisallowMultipleComponent]
[RequireComponent(typeof(Collider2D))]
public class SCollider :STransform,ISubPhysicsCollider
{
    [HideInInspector]

   public Collider2D AttachedCollider;
    
    /// <summary>
    /// 0,1,2,3分别代表右上左下
    /// </summary>
    [PureValueAtrribute]
    public List<int> ConnectState=new List<int> { 0 };
    [PureValueAtrribute]
    public List<Vector3Int> LocalMeshPos=new List<Vector3Int> { Vector3Int.zero};

    [PureValueAtrribute]
    public UInt32 AttachedRigidUnion;
    
    [PureValueAtrribute]
    public float Mass;
    Transform _parent;


    private ElementState state;

    public override void InitValueSetting()
    {
        base.InitValueSetting();
        Debug.Assert(this.gameObject.GetComponents<Collider2D>().Length == 1);
        AttachedCollider = this.gameObject.GetComponent<Collider2D>();
    }
    public override void SInit()
    {
        base.SInit();
        _parent = gameObject.transform.parent;
        collisionArgs = new List<CollisionArgs>();
    }
    public override void SOnDisable()
    {
        base.SOnDisable();
        collisionArgs.Clear();
    }
    public override void SStart()
    {
        base.SStart();
        state = Entity.GetComponent<SComValues>().ElementState;
    }
    public override void SOnDestory()
    {
        base.SOnDestory();
        SetParentBack();
    }


    public void SetParentBack()
    {

        gameObject.transform.SetParent(_parent);
        gameObject.transform.localEulerAngles = Vector3.zero;
        gameObject.transform.localScale = Vector3.zero;
    }
    private void DoDrawGizmos(List<Vector3Int>l1,List<int>l2)
    {
   //     Debug.Log(l1.Count);
        if (l1.Count != l2.Count)
        {
            return;
        }
        for (int i = 0; i < l1.Count; i++)
        {
            Vector3Int pos = l1[i];
            int sta = l2[i];

            Gizmos.DrawWireSphere(this.transform.TransformPoint((Vector3)pos * Main.ObejectBlockSize), Main.ObejectBlockSize / 2f);
        //    Debug.Log("pos=" + this.transform.TransformPoint((Vector3)pos * Main.ObejectBlockSize));
            for (int k = 0; k < 4; k++)
            {
                if ((sta & (1 << k)) <= 0) continue;
                Vector3 dir = new Vector3(Mathf.Cos(k * Mathf.PI / 2), Mathf.Sin(k * Mathf.PI / 2)) * (Main.ObejectBlockSize / 2-1);
      //          Debug.Log("p" + k + "=" + this.transform.TransformPoint((Vector3)pos * Main.ObejectBlockSize + dir));
       //         dir = this.transform.localToWorldMatrix.MultiplyVector(dir);
                Gizmos.DrawWireCube(this.transform.TransformPoint((Vector3)pos * Main.ObejectBlockSize + dir), Vector3.one*2);
            }   
        }
    }
    private void OnDrawGizmos()
    {
        DoDrawGizmos(LocalMeshPos, ConnectState);
    }

    List<CollisionArgs> collisionArgs = null;

    public List<CollisionArgs> GetCollisionArgs()
    {
        var ans = new List<CollisionArgs>(collisionArgs);
        collisionArgs.Clear();
        return ans;
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.collider.GetComponent<ISubPhysicsCollider>() == null)
        {
            Debug.LogWarning($"when { this} collide with {collision.collider.gameObject},interface not found");
        }
        else
        {
            var collideinfos = collision.collider.GetComponent<ISubPhysicsCollider>().GetCollideInfos(collision);
            foreach(var x in collideinfos)
            {
                collisionArgs.Add(new CollisionArgs
                {
                    StressedID = this.SData.CompIdentity,
                    StressedState=state,
                    StressedSystem=BelongingSystem.Default,
                    StressingID=x.Identity.Item1,
                    StressingState=x.Identity.Item3,
                    StressingSystem=x.Identity.Item2,
                    Info=new CollisionForceInfo { Force=x.Force,WorldPos=x.CollidePositionInWorld}
                }) ;
            }
        }
    }

    public Tuple<uint, BelongingSystem, ElementState> GetObjectInfo()
    {
        return new Tuple<uint, BelongingSystem, ElementState>(SData.CompIdentity, BelongingSystem.Default, state);
    }

    public List<CollideInfo> GetCollideInfos(Collision2D obj)
    {
        Debug.Assert(obj.collider.gameObject == this.gameObject);
        return new List<CollideInfo> { new CollideInfo(GetObjectInfo(),obj.GetContactPos(),obj.GetForce())};
    }
}
public static class SColliderEx
{
    public static Vector3Int GetMeshCenter(this SColliderVEx x)
    {
        var list = x.LocalMeshPos;
        var ans = Vector3Int.zero;
        foreach(var v in list)
        {
            ans += v;
        }
        ans /= list.Count;
        return ans;
    }
}